//
//  WordCounterJobs.swift
//  hello
//
//  Created by 赵康 on 2025/2/16.
//

import FluentSQL
import Queues
import Vapor

struct AlbumWordCountValidationJob: AsyncScheduledJob {
  // 定义任务名称
  let jobName = "album-word-count-validation"

  // 实现运行逻辑
  func run(context: QueueContext) async throws {
    _ = context.application.logger

    let validator = AlbumWordCountValidator(context: context)
    try await validator.validateAll()

  }
}

// 验证器实现
struct AlbumWordCountValidator {
  let context: QueueContext
  private let batchSize = 50
  private let maxRetries = 3

  // 验证所有专辑
  func validateAll() async throws {
    let db = context.application.db
    let logger = context.application.logger
    var offset = 0
    var hasMore = true
    var retryCount = 0

    while hasMore {
      do {
        let albums = try await fetchAlbumBatch(db: db, offset: offset)
        if albums.isEmpty {
          hasMore = false
          continue
        }

        try await validateBatch(albums: albums, db: db, logger: logger)
        offset += batchSize
        retryCount = 0  // 重置重试计数

      } catch {
        retryCount += 1
        logger.error("Error during validation batch: \(error)")

        if retryCount >= maxRetries {
          throw error  // 达到最大重试次数，抛出错误
        }

        // 等待后重试
        try await Task.sleep(nanoseconds: UInt64(pow(2.0, Double(retryCount))) * 1_000_000_000)
        continue
      }
    }
  }

  // 获取一批专辑
  private func fetchAlbumBatch(db: Database, offset: Int) async throws -> [Album] {
    try await Album.query(on: db)
      .with(\.$audios) { audio in
        audio.with(\.$transcripts)
      }
      .limit(batchSize)
      .offset(offset)
      .all()
  }

  // 验证并修复一批专辑
  private func validateBatch(albums: [Album], db: Database, logger: Logger) async throws {
    for album in albums {
      do {
        try await validateAlbum(album: album, db: db, logger: logger)
      } catch {
        logger.error("Error validating album \(album.id?.uuidString ?? "unknown"): \(error)")
        // 继续处理其他专辑，不中断整个批次
        continue
      }
    }
  }

  // 验证单个专辑
  private func validateAlbum(album: Album, db: Database, logger: Logger) async throws {
    let calculatedWordCount = try await calculateAlbumWordCount(album: album)

    if calculatedWordCount != album.wordCount {
      // 记录不匹配信息
      logger.warning(
        """
        Word count mismatch detected:
        Album ID: \(album.id?.uuidString ?? "unknown")
        Title: \(album.title)
        Stored count: \(album.wordCount)
        Calculated count: \(calculatedWordCount)
        """
      )

      // 更新专辑词数
      album.wordCount = calculatedWordCount
      try await album.save(on: db)

      // 记录修复操作
      try await logValidationFix(
        albumId: album.id,
        oldCount: album.wordCount,
        newCount: calculatedWordCount,
        db: db
      )
    }
  }

  // 计算专辑实际词数
  private func calculateAlbumWordCount(album: Album) async throws -> Int {
    var totalCount = 0
    for audio in album.audios {
      for transcript in audio.transcripts {
        if transcript.isDeleted != true {
          totalCount += transcript.wordCount
        }
      }
    }
    return totalCount
  }

  // 记录修复日志
  private func logValidationFix(
    albumId: UUID?,
    oldCount: Int,
    newCount: Int,
    db: Database
  ) async throws {
    guard let albumId = albumId else { return }

    // 创建验证日志记录
    let log = ValidationLog(
      albumId: albumId,
      oldWordCount: oldCount,
      newWordCount: newCount,
      createdAt: Date()
    )
    try await log.save(on: db)
  }
}
